package com.blog.service;

import com.blog.dao.BlogDAO;
import com.blog.dao.TypeDAO;
import com.blog.dao.UserDAO;

import com.blog.domain.Blog;
import com.blog.domain.Type;
import com.blog.domain.User;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**
 * Spring service that handles CRUD requests for Type entities
 * 
 */

@Service("TypeService")
@Transactional
public class TypeServiceImpl implements TypeService {

	/**
	 * DAO injected by Spring that manages Blog entities
	 * 
	 */
	@Autowired
	private BlogDAO blogDAO;

	/**
	 * DAO injected by Spring that manages Type entities
	 * 
	 */
	@Autowired
	private TypeDAO typeDAO;

	/**
	 * DAO injected by Spring that manages User entities
	 * 
	 */
	@Autowired
	private UserDAO userDAO;

	/**
	 * Instantiates a new TypeServiceImpl.
	 *
	 */
	public TypeServiceImpl() {
	}

	/**
	 * Return all Type entity
	 * 
	 */
	@Transactional
	public List<Type> findAllTypes(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Type>(typeDAO.findAllTypes(startResult, maxRows));
	}

	/**
	 */
	@Transactional
	public Type findTypeByPrimaryKey(Integer id) {
		return typeDAO.findTypeByPrimaryKey(id);
	}

	/**
	 * Load an existing Type entity
	 * 
	 */
	@Transactional
	public Set<Type> loadTypes() {
		return typeDAO.findAllTypes();
	}

	/**
	 * Delete an existing User entity
	 * 
	 */
	@Transactional
	public Type deleteTypeUser(Integer type_id, Integer related_user_id) {
		Type type = typeDAO.findTypeByPrimaryKey(type_id, -1, -1);
		User related_user = userDAO.findUserByPrimaryKey(related_user_id, -1, -1);

		type.setUser(null);
		related_user.getTypes().remove(type);
		type = typeDAO.store(type);
		typeDAO.flush();

		related_user = userDAO.store(related_user);
		userDAO.flush();

		userDAO.remove(related_user);
		userDAO.flush();

		return type;
	}

	/**
	 * Save an existing Type entity
	 * 
	 */
	@Transactional
	public void saveType(Type type) {
		Type existingType = typeDAO.findTypeByPrimaryKey(type.getId());

		if (existingType != null) {
			if (existingType != type) {
				existingType.setId(type.getId());
				existingType.setName(type.getName());
			}
			type = typeDAO.store(existingType);
		} else {
			type = typeDAO.store(type);
		}
		typeDAO.flush();
	}

	/**
	 * Save an existing User entity
	 * 
	 */
	@Transactional
	public Type saveTypeUser(Integer id, User related_user) {
		Type type = typeDAO.findTypeByPrimaryKey(id, -1, -1);
		User existinguser = userDAO.findUserByPrimaryKey(related_user.getId());

		// copy into the existing record to preserve existing relationships
		if (existinguser != null) {
			existinguser.setId(related_user.getId());
			existinguser.setUsername(related_user.getUsername());
			existinguser.setPassword(related_user.getPassword());
			existinguser.setNickName(related_user.getNickName());
			existinguser.setSex(related_user.getSex());
			existinguser.setRegister(related_user.getRegister());
			existinguser.setImage(related_user.getImage());
			related_user = existinguser;
		} else {
			related_user = userDAO.store(related_user);
			userDAO.flush();
		}

		type.setUser(related_user);
		related_user.getTypes().add(type);
		type = typeDAO.store(type);
		typeDAO.flush();

		related_user = userDAO.store(related_user);
		userDAO.flush();

		return type;
	}

	/**
	 * Return a count of all Type entity
	 * 
	 */
	@Transactional
	public Integer countTypes() {
		return ((Long) typeDAO.createQuerySingleResult("select count(o) from Type o").getSingleResult()).intValue();
	}

	/**
	 * Delete an existing Type entity
	 * 
	 */
	@Transactional
	public void deleteType(Type type) {
		typeDAO.remove(type);
		typeDAO.flush();
	}

	/**
	 * Delete an existing Blog entity
	 * 
	 */
	@Transactional
	public Type deleteTypeBlogs(Integer type_id, Integer related_blogs_id) {
		Blog related_blogs = blogDAO.findBlogByPrimaryKey(related_blogs_id, -1, -1);

		Type type = typeDAO.findTypeByPrimaryKey(type_id, -1, -1);

		related_blogs.setType(null);
		type.getBlogs().remove(related_blogs);

		blogDAO.remove(related_blogs);
		blogDAO.flush();

		return type;
	}

	/**
	 * Save an existing Blog entity
	 * 
	 */
	@Transactional
	public Type saveTypeBlogs(Integer id, Blog related_blogs) {
		Type type = typeDAO.findTypeByPrimaryKey(id, -1, -1);
		Blog existingblogs = blogDAO.findBlogByPrimaryKey(related_blogs.getId());

		// copy into the existing record to preserve existing relationships
		if (existingblogs != null) {
			existingblogs.setId(related_blogs.getId());
			existingblogs.setTitle(related_blogs.getTitle());
			existingblogs.setContent(related_blogs.getContent());
			existingblogs.setDate(related_blogs.getDate());
			existingblogs.setReader(related_blogs.getReader());
			related_blogs = existingblogs;
		} else {
			related_blogs = blogDAO.store(related_blogs);
			blogDAO.flush();
		}

		related_blogs.setType(type);
		type.getBlogs().add(related_blogs);
		related_blogs = blogDAO.store(related_blogs);
		blogDAO.flush();

		type = typeDAO.store(type);
		typeDAO.flush();

		return type;
	}
}
